package structure;

import java.util.ArrayList;
import java.util.List;



public class grid implements ICellEventListener{

	private cell[][] cells = new cell[9][9];
	private row[] rows = new row[9];
	private col[] cols = new col[9];
	private blk[] blks = new blk[9];
	
	
	
	public grid() {
		for (int i = 0; i < 9; i++) {
			rows[i] = new row(i);
			cols[i] = new col(i);
			blks[i] = new blk(i);
		}
		
		for (int r=0; r<9; r++) {
			for (int c=0; c<9; c++) {
				cells[r][c] = new cell(this, r, c, 0);
				//subscribe to events
				cells[r][c].subscribe(this);
				
				//add cell to appropriate groups
				rows[r].add(cells[r][c]);
				cols[c].add(cells[r][c]);
				blks[getBlkByCoord(r, c).getID()].add(cells[r][c]);
			}
		}
	}
	
	public cell getCell(int r, int c) { return this.cells[r][c]; }
	public row getRow(int id) { return this.rows[id]; }
	public col getCol(int id) { return this.cols[id]; }
	public blk getBlk(int id) { return this.blks[id]; }
	public blk getBlk(int rID, int cID) { return this.blks[rID * 3 + cID]; }
	
	public row getRowByCoord(int r, int c) { return this.rows[r]; }
	public col getColByCoord(int r, int c) { return this.cols[c]; }
	public blk getBlkByCoord(int r, int c) { return this.blks[(r/3) * 3 + (c / 3)]; }
	
	public int getCellValue(int r, int c) { return this.cells[r][c].getValue(); }
	public void setCellValue(int r, int c, int val) { this.cells[r][c].setValue(val); }
	
	
	public group[] getGroups(Class<? extends group> grouptype) {
		if (grouptype == row.class) return this.rows;
		else if (grouptype == col.class) return this.cols;
		else return this.blks;
	}
	
    public List<Class<? extends group>> getGroupTypes() {
        ArrayList<Class<? extends group>> list = new ArrayList<Class<? extends group>>(3);
        list.add(blk.class);
        list.add(row.class);
        list.add(col.class);
        return list;
    }

    public group getGroupAt(Class<? extends group> grouptype, int r, int c) {
        if (grouptype.equals(row.class))
            return getRowByCoord(r, c);
        else if (grouptype.equals(col.class))
            return getColByCoord(r, c);
        else
            return getBlkByCoord(r, c);
    }

    public group getGroupAt(Class<? extends group> regionType, cell c) {
        return getGroupAt(regionType, c.getRowID(), c.getColID());
    }
	
	
	
	
	
	
	
	@Override
	public void handleEventCellChanged(cell e) {
		System.out.println("Cell Changed: " + e.toStringDetails());
	}
	

}
